package com.fancy.application.sys.permission.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.fancy.application.common.constant.Constants;
import com.fancy.application.common.utils.RedisUtil;
import com.fancy.application.sys.permission.entity.Auth;
import com.fancy.application.sys.permission.entity.BaseModuleEntity;
import com.fancy.application.sys.permission.entity.Request;
import com.fancy.application.sys.permission.entity.RoleResource;
import com.fancy.application.sys.permission.service.IDataLoadService;
import com.fancy.application.sys.permission.service.ISysPermissionResService;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Log4j2
@Component
public class DataLoadService implements IDataLoadService {
    @Resource
    private RedisUtil redisUtil;


    @Override
    public void load() {
        //此处加载模块配置
        File rootFile = getRootFile();
        if(rootFile.isDirectory()){
            List<JSONObject> jsonObjectList = getJSONFiles(rootFile);
            List<BaseModuleEntity> baseModuleEntities = new ArrayList<>();
            jsonObjectList.forEach(jsonObject -> {
                BaseModuleEntity baseModuleEntity = new BaseModuleEntity();
                baseModuleEntity.setFdName(jsonObject.getStr("name"));
                baseModuleEntity.setFdOrder(jsonObject.getInt("order"));
                baseModuleEntity.setFdPath(jsonObject.getStr("urlPrefix"));
                //加载权限列表
                JSONArray roles = jsonObject.getJSONArray("roles");
                roles.forEach(o -> {    //获取权限定义
                    JSONObject roleObj = (JSONObject)o;
                    String value = roleObj.getStr("value");
                    String name = roleObj.getStr("name");
                    String description = roleObj.getStr("description");
                    RoleResource roleResourceEntity = new RoleResource();
                    roleResourceEntity.setDescription(description);
                    roleResourceEntity.setName(name);
                    roleResourceEntity.setValue(value);
                    baseModuleEntity.getRoleResources().add(roleResourceEntity);
                });
                //加载请求列表
                JSONArray requests = jsonObject.getJSONArray("request");
                requests.forEach(o -> {
                    JSONObject requestObj = (JSONObject) o;
                    Request request = getRequest(requestObj);
                    JSONArray children = requestObj.getJSONArray("children");
                    if(children!=null){
                        children.forEach(o1 -> {
                            JSONObject requestObjChild = (JSONObject) o1;
                            Request requestChild = getRequest(requestObjChild);
                            request.getChildren().add(requestChild);
                        });
                    }

                    baseModuleEntity.getRequests().add(request);
                });
                //加载权限验证
                JSONObject auths = jsonObject.getJSONObject("auth");
                if(auths!=null){
                    baseModuleEntity.getAuths().add(getAuth(auths));
                }
                baseModuleEntities.add(baseModuleEntity);
            });
            //模块存入redis的key值
            redisUtil.delKeys(Constants.MODULE_KEY);
            redisUtil.set(Constants.MODULE_KEY,baseModuleEntities,-1);   //设置模块列表
            log.debug("模块加载成功!");
            log.debug("权限资源加载成功!");
            log.debug("权限列表加载成功!");
        }

    }


    private File getRootFile() {
        String resourceDir = System.getProperty("user.dir") + File.separator +"resources/config/json";
        if(!FileUtil.exist(resourceDir)){
            resourceDir = System.getProperty("user.dir") + File.separator +"src/main/resources/config/json";
        }
        log.info("临时文件路径为{}", resourceDir);
        return FileUtil.file(resourceDir);
    }

    /**
     * 按模块展示
     * @return
     */
    @Override
    public List<BaseModuleEntity> getModules() {
        return (List<BaseModuleEntity>) redisUtil.get(Constants.MODULE_KEY);
    }

    @Override
    public List<RoleResource> getRoleResourceByModulePath(String fdId) {
        BaseModuleEntity entity = null;
        List<BaseModuleEntity> baseModuleEntities = (List<BaseModuleEntity>) redisUtil.get(Constants.MODULE_KEY);
        Optional<BaseModuleEntity> baseModuleEntityOptional = baseModuleEntities.stream().filter(baseModuleEntity -> StrUtil.equals(baseModuleEntity.getFdPath(), fdId) ).findFirst();
        if(baseModuleEntityOptional.isPresent()){
            entity = baseModuleEntityOptional.get();
        }
        if(entity!= null){
            return entity.getRoleResources();
        }else{
            return null;
        }
    }

    @Override
    public List<RoleResource> getAllRoleResource() {
        List<RoleResource> roleResources = new ArrayList<>();
        List<BaseModuleEntity> baseModuleEntities = (List<BaseModuleEntity>) redisUtil.get(Constants.MODULE_KEY);
        baseModuleEntities.forEach(baseModuleEntity -> roleResources.addAll(baseModuleEntity.getRoleResources()) );
        return roleResources;
    }

    /**
     * 加载数据权限的配置
     */
    public Auth getAuth(JSONObject requestObj) {
        String modelName = requestObj.getStr("modelName");
        JSONArray array = requestObj.getJSONArray("authFilter");
        List<String> authFilters = array.toList(String.class);
        Auth auth = new Auth();
        auth.setModelName(modelName);
        auth.setAUthFilter(authFilters);
        return auth;
    }

    private Request getRequest(JSONObject requestObj){
        String path = requestObj.getStr("path");
        String role = requestObj.getStr("role");
        String method = requestObj.getStr("method");
        if(StrUtil.isBlank(method)) method = "";
        Request request = new Request();
        request.setPath(path);
        request.setRole(role);
        request.setMethod(method);
        return request;

    }

    /**
     * 转换成json
     * @param rootFile
     * @return
     */
    private List<JSONObject> getJSONFiles(File rootFile) {
        List<File> files = getFileList(rootFile);
        List<JSONObject> objects = new ArrayList<>();
        for(File file:files){
            String jsonStr = FileUtil.readString(file, CharsetUtil.defaultCharset());
            JSONObject jsonObject= JSONUtil.parseObj(jsonStr);
            objects.add(jsonObject);
        }
        return objects;
    }
    /**
     *获取目录下所有的json文件
     * @param
     * @return
     */
    public List<File> getFileList(File dir) {
        List<File> fileList = new ArrayList<>();
        List<File> files = FileUtil.loopFiles(dir);// 该文件目录下文件全部放入数组
        if (files != null&&files.size()>0) {
            for (File file : files) {
                String fileName = file.getName();
                if (file.isDirectory()) { // 判断是文件还是文件夹
                    fileList.addAll(getFileList(FileUtil.file(file.getAbsolutePath()))); // 获取文件绝对路径
                } else if (fileName.endsWith("json")) { // 判断文件名是否以.json结尾
                    fileList.add(file);
                }
            }
        }
        return fileList;
    }


}
